#include "Module.h"

#include <errno.h>

#ifdef WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif

Module::Module(std::string name)
{
#ifdef WIN32
	SetErrorMode(SEM_FAILCRITICALERRORS);
	handle = LoadLibraryA(name.c_str());
	if (!handle)
	{
		printf("Module.Module: handle == NULL. name=`%s` Error code: %d\n", name.c_str(), GetLastError());
	}
#else
	handle = dlopen(name.c_str(), RTLD_LAZY);
	if (!handle)
	{
		printf("Module.Module: handle == NULL. name=`%s` Error: %s\n", name.c_str(), dlerror());
	}
#endif
}

Module::~Module()
{
#ifdef WIN32
	FreeLibrary((HMODULE)handle);
#else
	dlclose(handle);
#endif
}

void* Module::GetFunc(std::string name)
{
	void* func = NULL;
	if (!handle)
	{
		printf("Module.GetFunc: handle == NULL\n");
		return NULL;
	}
#ifdef WIN32
	func = GetProcAddress((HMODULE)handle, name.c_str());
	if (!func)
	{
		fprintf(stderr, "Module.GetFunc: Could not get function `%s`. Error code: %d\n", name.c_str(), GetLastError());
		return NULL;
	}
#else
	func = dlsym(handle, name.c_str());
	if (!func)
	{
		fprintf(stderr, "Module.GetFunc: Could not get function `%s`. Error: %s\n", name.c_str(), dlerror());
		return NULL;
	}
#endif
	return func;
}

bool Module::HasFunc(std::string name)
{
	void* func = NULL;
	if (!handle)
	{
		return false;
	}
#ifdef WIN32
	SetErrorMode(SEM_FAILCRITICALERRORS);
	func = GetProcAddress((HMODULE)handle, name.c_str());
#else
	func = dlsym(handle, name.c_str());
#endif
	return func != NULL;
}
